/*
 * Copyright (c) 2008 Ricardo Rocha, rocha.porto@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.gliding.kumulus.client;

import java.util.Date;

import org.gliding.kumulus.client.model.ActivityDaySummary;
import org.gliding.kumulus.client.model.KumulusContext;
import org.gliding.kumulus.client.model.Member;
import org.gliding.kumulus.client.model.PlanningContext;
import org.gliding.kumulus.client.model.PlanningContextUpdateListener;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Class defining the week view of the Planning component.
 * 
 * @author Ricardo Rocha <rocha.porto@gmail.com>
 * @version $Rev:: $
 * 
 * @see org.gliding.kumulus.client.Planning
 */
public class PlanningView extends Composite implements PlanningContextUpdateListener {

	/**
	 * The full planning view panel.
	 */
	private HorizontalPanel viewPanel = new HorizontalPanel();
    
	/**
	 * The date formatter use for the day header in the planning view panel.
	 */
	public static DateTimeFormat dayHeaderDateFormat = DateTimeFormat.getFormat("EEE (dd MMM)");
	
	/**
	 * Pointer to the current planning context, common to the whole application.
	 */
	private PlanningContext planningCtx;
	
	/**
	 * Class constructor.
	 */
	public PlanningView(PlanningContext planningCtx) {
		
		// Set the local planning context to point to the global given context
		this.planningCtx = planningCtx;
				
        // Initialize the widget and set the CSS style
	    initWidget(viewPanel);
        setStyleName("kumulus-PlanningView");
    }
	
	/**
	 * Redraws the full planning view panel, taking the current data in the Planning context
	 * into account.
	 */
	public void redraw() {
        
        Kumulus.setMessage("Drawing Planning View Panel...");
        viewPanel.clear();
		
		// The ActivityDaySummary object currently active (corresponding to the selected period)
		ActivityDaySummary[] activeDaySummaries = this.planningCtx.getActiveDaySummaries();
		
		// Iterate through the list of active summaries, redrawing each panel
		for(int i=0; i<activeDaySummaries.length; i++) {
			// Holds the full day contents (header, morning, afternoon)
			VerticalPanel dayPanel = new VerticalPanel();
		
			// Add the header for this day
			SimplePanel dayHeaderPanel = new SimplePanel();
			dayHeaderPanel.add(new Hyperlink(dayHeaderDateFormat.format(activeDaySummaries[i].getDate()), ""));
			dayHeaderPanel.setStyleName("kumulus-PlanningViewDayHeader");
			dayPanel.add(dayHeaderPanel);
			dayPanel.setCellHeight(dayHeaderPanel, "2%");
		
			// Add the morning part of this day
			VerticalPanel morningPanel = this.getHalfDayPanel(ActivityDaySummary.MORNING, activeDaySummaries[i]);
			dayPanel.add(morningPanel);
			dayPanel.setCellHeight(morningPanel, "49%");	
		
			// Add the afternoon part of this day
			VerticalPanel afternoonPanel = this.getHalfDayPanel(ActivityDaySummary.AFTERNOON, activeDaySummaries[i]);
			dayPanel.add(afternoonPanel);
			dayPanel.setCellHeight(afternoonPanel, "49%");	
		
			dayPanel.setStyleName("kumulus-PlanningViewDay");
		
			// Add the day panel
			viewPanel.add(dayPanel);
            
            Kumulus.setMessage("");
		}
	}

	/**
	 * Returns a Panel object containing the drawing of a half day activity.
	 * 
	 * @param partOfDay The part of the day to be drawn and returned (ActivityDaySummary.MORNING/AFTERNOON)
	 * @param activityDaySummary The object containing the full day activity to be drawn
	 * @return A panel object containing the rendering of a half day activity
	 * @see ActivityDaySummary
	 */
	public VerticalPanel getHalfDayPanel(int partOfDay, ActivityDaySummary activityDaySummary) {
		// The container panel for the half day
		VerticalPanel halfDayPanel = new VerticalPanel();
		// The internal panel containing all the members
		VerticalPanel halfDayMembersPanel = new VerticalPanel();
		halfDayMembersPanel.setStyleName("kumulus-PlanningViewMembers");
		
		// Fetch the currently active roles
		String[] memberRoles = this.planningCtx.getActiveMemberRoles();
		
		// For each active role, draw the ones with activity
		for (int i=0; i<memberRoles.length; i++) {
			// Fetch all activity entries for this role and part of day
			Member[] activityMembers = activityDaySummary.getActivityEntries(memberRoles[i], partOfDay);
			// If not empty, render
			if (activityMembers.length != 0) {
				// Iterate through each activity entry
				for (int j=0; j<activityMembers.length; j++) {
					// Add the member entry to the planning view
					halfDayMembersPanel.add(new MemberEntry(activityDaySummary.getDate(), partOfDay, 
							activityMembers[j], memberRoles[i]));
				}
				halfDayMembersPanel.add(new HTML("<hr/>"));				
			}
		}
	
		// Add the internal members panel to the half day container
		halfDayPanel.add(halfDayMembersPanel);
		halfDayPanel.setStyleName("kumulus-PlanningViewHalfDay");
		
		return halfDayPanel;
	}
    
	/**
	 * @see PlanningContextUpdateListener.onDateUpdate()
	 */
    public void onDateUpdate(PlanningContext ctx) {
        this.redraw();
    }
   
    /**
	 * @see PlanningContextUpdateListener.onEntryRemoval()
	 */
	public void onEntryRemoval(PlanningContext ctx) {
		this.redraw();		
	}
    
	/**
     * Class definition for a member entry in the PlanningView panel.
     */
    private class MemberEntry extends Composite implements ClickListener {

        /**
         * The date corresponding to this entry.
         */
        private Date date;
        
        /**
         * The part of the day corresponding to this entry (ActivityDaySummary.MORNING/AFTERNOON).
         */
        private int partOfDay;
        
        /**
         * The member corresponding to this entry.
         */
        private Member member;
        
        /**
         * The role of the member in this entry.
         */
        private String role;
        
        /**
         * The panel object hosting this widget.
         */
        private SimplePanel entryPanel = new SimplePanel();
        
        /**
         * The panel object hosting the text representation of this widget.
         */
        private SimplePanel entryTextPanel = new SimplePanel();
        
        /**
         * Class constructor.
         * 
         * @param date The Date object of this entry
         * @param member The Member object of this entry
         * @param role The role of the member in this entry
         */
        public MemberEntry(Date date, int partOfDay, Member member, String role) {

        	this.date = date;
        	this.partOfDay = partOfDay;
            this.member = member;
            this.role = role;
            
            Hyperlink entryLink = new Hyperlink();
            entryLink.setText(this.member.lastName + ", " + this.member.firstName);
            entryLink.addClickListener(this);
            this.entryTextPanel.add(entryLink);
            this.entryPanel.add(entryTextPanel);
            
            this.entryPanel.setStyleName("kumulus-PlanningView" + this.role);
            if (KumulusContext.getKumulusContext().isLogged(this.member.id)) {
            	this.entryTextPanel.setStyleName("kumulus-PlanningViewLoggedMember");
            }
            initWidget(this.entryPanel);
        }
        
        /**
         * Handler for all click events on this widget.
         * 
         * @param clickedWidget The widget object that was clicked
         */
        public void onClick(Widget clickedWidget) {
            PlanningContext.getPlanningContext().removeMemberActivity(this.date, this.role, 
            		this.partOfDay, this.member.id);
        }
        
    }
	
}
